package org.example.java.util.concurrency.ground_floor;

/**
 * synchronized 锁的是代码执行块
 * 对象的锁 与 对对象的操作是两个概念
 * java的内存模型（lock unlock read load assign use store write）
 * -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails
 * Created by Juntao.Zhang on 2014/11/17.
 */
public class MemExchange {
  private static void sleep(long time) {
    try {
      Thread.sleep(time);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

  static class Thing {
    public String flag = "true";
    @Override
    public String toString() { return "Thing{flag=" + flag + '}'+super.toString(); }
  }

  static class MyRun implements Runnable{
    Thing thing;
    private boolean pleaseStop = false;
    //    private volatile boolean pleaseStop = false;
    public void tellMeToStop() { pleaseStop = true; }
    MyRun(Thing thing) { this.thing = thing; }
    public void run() {
      System.out.println(Thread.currentThread().getName()+" started");
      for (int i = 0; i < allocation1.length; i++) allocation1[i]=0;
      System.out.println("task1 flag  " + flag);
      System.out.println("task1 before  " + thing);
      flag=false;
      //cpu 让出线程后 再次回来执行将获取最新值
      while (!pleaseStop) {
        print(thing, "false", 2000, "task1");
        Thread.yield();
      }
      System.out.println("task1 after " + thing);
      System.out.println("task1 flag  " + flag);
      System.out.println(Thread.currentThread().getName()+" end");
    }
  }
  static class MyRun2 implements Runnable {
    private boolean pleaseStop = false;
//    private volatile boolean pleaseStop = false;
    public void run() {
      System.out.println(Thread.currentThread().getName()+" started");
      int i = 0;
//      while (!pleaseStop) i++;
      while (!pleaseStop) Thread.yield();
      System.out.println(i);
      System.out.println(Thread.currentThread().getName()+" end");
    }
    public void tellMeToStop() {
      pleaseStop = true;
    }
  }
  private static boolean flag = false;//一般变量
  static  byte[] allocation1 = new byte[2 * 1024 * 1024];
  public static void main(String[] args) {
    final Thing thing = new Thing();//被锁的对象
    MyRun myRun = new MyRun(thing);
//    MyRun myRun = new MyRun();
    MyRun2 myRun2 = new MyRun2();
    new Thread(myRun , "task1").start();
//    new Thread(myRun2 , "task3").start();
    new Thread(new Runnable() {
      public void run() {
        System.out.println(Thread.currentThread().getName()+" started");
        for (int i = 0; i < allocation1.length; i++) allocation1[i]=1;
        System.out.println("task2 before  " + thing);
//        thing.flag = "!!!";
        sleep(100);
        flag=true;
//        myRun.tellMeToStop();
        print2(thing, "???", 1000, "task2");
        System.out.println("task2 after " + thing);
        System.out.println(Thread.currentThread().getName()+" end");
      }
    }, "task2").start();
    sleep(3000);
    myRun.tellMeToStop();
    myRun2.tellMeToStop();
    System.out.println(allocation1[0]);
    System.out.println(allocation1[1]);
  }

  private static void print(Thing thing, String flag, long time, String name) {
    synchronized (thing) {
      System.out.println(name + " print " + thing);
      sleep(time);
      thing.flag = flag;
      System.out.println(name + " print " + thing);
    }
  }
  private static void print2(Thing thing, String flag, long time, String name) {
    synchronized (thing) {
      System.out.println(name + " print2  " + thing);
      sleep(time);
//      thing.flag = flag;
      System.out.println(name + " print2  " + thing);
    }
  }
}
